package horizon.frame;

import genesisclient.GenesisClient;
import horizon.animations.AnimationCache;
import horizon.graphics.RenderingContext;

import horizon.states.State;
import horizon.states.StateManager;
import horizon.util.InputManager;
import horizon.util.Vector2;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Frame extends JFrame {

    InputManager input;
    StateManager stateManager = new StateManager();
    RenderingContext r;
    public static boolean exitRequested = false;
    public static int frameRate = 100;
    public static int fps = 0;
    boolean fpsShown = true;
    JPanel canvas = new JPanel();
    BufferedImage buffer;
    Graphics2D g;
    Graphics2D buff;
    int flag = 0;
    Dimension canvasSize;

    public Frame(String title, int width, int height) {
        this.setTitle(title);
        this.setResizable(false);
        this.setSize(width, height);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);

        canvasSize = new Vector2(width , height).getDim();

        init();

        Thread gameLoop = new Thread() {

            @Override
            public void run() {

                long fpsTime = System.currentTimeMillis();
                long lastTime = System.currentTimeMillis();
                long lastUpdate = System.currentTimeMillis();
                int frames = 0;

                while (!exitRequested) {



                    if (System.currentTimeMillis() - lastTime >= (1000 / frameRate)) {

                        input.update();
                        update(System.currentTimeMillis() - lastUpdate);
                        lastUpdate = System.currentTimeMillis();
                        render();
                        frames++;
                        lastTime = System.currentTimeMillis();

                    }
                    if (System.currentTimeMillis() - fpsTime >= 1000) {


                        fps = frames;
                        frames = 0;
                        fpsTime = System.currentTimeMillis();

                    }

                }

            }
        };
        gameLoop.setName("GameLoop");
        gameLoop.start();

    }

    public void init() {


        //Dimension dim = getSize();
        
        canvas = (JPanel) this.getContentPane();
        canvas.setPreferredSize(canvasSize);
        pack();
        
        int w = canvasSize.width;
        int h = canvasSize.height;
    
        
        buffer = (BufferedImage) createImage(w, h);
        
        buff = buffer.createGraphics();
        
        r = new RenderingContext(buff);
        
        System.out.println("Create buffer: " + canvasSize);
  
        GenesisClient.canvasHeight = canvas.getHeight();
        GenesisClient.canvasWidth = canvas.getWidth();
        
        canvas.setBackground(Color.white);
        g = (Graphics2D) canvas.getGraphics();

        input = InputManager.getInstance();
        this.addKeyListener(input);
        canvas.addMouseListener(input);
        canvas.addMouseMotionListener(input);

        AnimationCache.loadAnimations();

    }

    public void update(long elapsedTime) {

        stateManager.update(elapsedTime);

    }

    public void render() {

        stateManager.render(r);


        //BufferShit
        if (fpsShown) {
            r.drawText("FPS: " + String.valueOf(fps), new Vector2(0, 10), Color.white);
        }
        g.drawImage(buffer, 0, 0, this);
        buff.setColor(Color.white);
        buff.clearRect(0, 0, getWidth(), getHeight());

    }

    public void setFpsShown(boolean t) {
        fpsShown = t;
    }

    public void addState(State s) {

        this.stateManager.pushState(s);

    }
}
